﻿using AutoMapper;
using com.ytocargo.Application.FlightInfos.Dto;
using com.ytocargo.Core.FlightInfo4Monitors;
using com.ytocargo.Core.FlightInfoSubs;
using System;
using System.Text.RegularExpressions;

namespace com.ytocargo.Application
{
    public class AutoMapperProfile : Profile
    {
        public AutoMapperProfile()
        {
            CreateMap<FlightInfoDto, FlightInfo4Monitor>()
                .ForMember(m => m.Id, options => options.Ignore())
                .ForMember(m => m.FlightId, options => options.MapFrom(f => f.Id))
                .ForMember(m => m.FltId, options => options.MapFrom(f => GetFltId(f.FlightNo)))
                .ForMember(m => m.FltIdFix, options => options.MapFrom(f => GetFltIdFix(f.FlightNo)))
                .ForMember(m => m.FltDate, options => options.MapFrom(f => f.FlightDate.ToUniversalTime()))
                .ForMember(m => m.FltType, options => options.MapFrom(f => f.DOrI))
                .ForMember(m => m.FltOpType, options => options.MapFrom(f => f.DOrI))
                .ForMember(m => m.FltStatus, options => options.MapFrom(f => GetFltStatusCode(f)))
                .ForMember(m => m.Std, options => options.MapFrom(f => f.Std.ToUniversalTime()))
                .ForMember(m => m.Sta, options => options.MapFrom(f => f.Sta.ToUniversalTime()))
                .ForMember(m => m.SchDepApt, options => options.MapFrom(f => f.airPortInfoDep.AIRPORT_3CODE))
                .ForMember(m => m.SchArrApt, options => options.MapFrom(f => f.airPortInfoArr.AIRPORT_3CODE))
                .ForMember(m => m.Etd, options => options.MapFrom(f => ConvertUTC(f.Etd)))
                .ForMember(m => m.Eta, options => options.MapFrom(f => ConvertUTC(f.Eta)))
                .ForMember(m => m.DepApt, options => options.MapFrom(f => f.airPortInfoDep.AIRPORT_3CODE))
                .ForMember(m => m.ArrApt, options => options.MapFrom(f => f.airPortInfoArr.AIRPORT_3CODE))
                .ForMember(m => m.TaxioutTime, options => options.MapFrom(f => ConvertUTC(f.Out)))
                .ForMember(m => m.TaxiinTime, options => options.MapFrom(f => ConvertUTC(f.Inn)))
                .ForMember(m => m.OffTime, options => options.MapFrom(f => ConvertUTC(f.AcarsAtd.HasValue ? f.AcarsAtd : f.Atd)))
                .ForMember(m => m.OnTime, options => options.MapFrom(f => ConvertUTC(f.AcarsAta.HasValue ? f.AcarsAta : f.Ata)))

                .ForMember(m => m.CargoDoorCloseTimeLocal, options => options.MapFrom(f => f.CloseDoorTime.HasValue ? f.CloseDoorTime : f.Out))
                .ForMember(m => m.StdLocal, options => options.MapFrom(f => f.Std))
                .ForMember(m => m.StaLocal, options => options.MapFrom(f => f.Sta))
                .ForMember(m => m.EtdLocal, options => options.MapFrom(f => f.Etd))
                .ForMember(m => m.EtaLocal, options => options.MapFrom(f => f.Eta))
                .ForMember(m => m.TaxioutTimeLocal, options => options.MapFrom(f => f.Out))
                .ForMember(m => m.TaxiinTimeLocal, options => options.MapFrom(f => f.Inn))
                .ForMember(m => m.FltIdPk, options => options.MapFrom(f => f.Id))
                ;

            CreateMap<FlightInfoDto, FlightInfoSub>()
                .ForMember(m => m.AcId, options => options.MapFrom(f => f.AcReg))
                .ForMember(m => m.AcType, options => options.MapFrom(f => f.AcType))
                .ForMember(m => m.AcTypeMarket, options => options.MapFrom(f => f.airCraftInfo.AcTypeLong))
                .ForMember(m => m.AltApt1, options => options.MapFrom(f => f.airPortInfoFpl1.AIRPORT_3CODE))
                .ForMember(m => m.AltApt2, options => options.MapFrom(f => f.airPortInfoFpl2.AIRPORT_3CODE))
                .ForMember(m => m.AcSeatsLayout, options => options.MapFrom(f => f.airCraftInfo.Layout))
                ;
        }

        private static DateTime? ConvertUTC(DateTime? date)
        {
            if (date.HasValue)
            {
                return new DateTime?(date.Value.ToUniversalTime());
            }
            else
            {
                return new DateTime?();
            }
        }

        private static string GetFltStatusCode(FlightInfoDto flightInfoDto)
        {
            if (flightInfoDto.FlgCs == "C" || flightInfoDto.AdjustType == "0")
            {
                return "2";
            }

            if (flightInfoDto.AdjustType == "R")
            {
                return "4";
            }

            if (flightInfoDto.AdjustType == "V")
            {
                return "3";
            }

            return "0";
        }

        private static string GetFltId(string flightNo)
        {
            string pattern = @"\b(?<a>[a-zA-Z]*)(?<b>\d+)(?<c>[a-zA-Z]*)\b";
            MatchCollection matches = Regex.Matches(flightNo, pattern);
            string result = flightNo;
            foreach (Match match in matches)
            {
                GroupCollection groups = match.Groups;
                if (groups["b"] != null)
                {
                    result = groups["b"].Value;
                    break;
                }
            }
            if (!string.IsNullOrWhiteSpace(result))
            {
                if (result.Length < 3)
                {
                    result = result.PadLeft(3, '0');
                }
            }
            return result;
        }

        private static string GetFltIdFix(string flightNo)
        {
            string pattern = @"\b(?<a>[a-zA-Z]*)(?<b>\d+)(?<c>[a-zA-Z]*)\b";
            MatchCollection matches = Regex.Matches(flightNo, pattern);
            string result = flightNo;
            foreach (Match match in matches)
            {
                GroupCollection groups = match.Groups;
                if (groups["c"] != null)
                {
                    result = groups["c"].Value;
                    break;
                }
            }
            return result;
        }
    }
}
